package top.ltc_cn.minecraft_manager.utils;

import com.nimbusds.jose.JOSEException;
import com.nimbusds.jose.JWSAlgorithm;
import com.nimbusds.jose.JWSVerifier;
import com.nimbusds.jose.Payload;
import com.nimbusds.jose.crypto.RSASSAVerifier;
import com.nimbusds.jwt.SignedJWT;
import org.springframework.stereotype.Service;
import top.ltc_cn.minecraft_manager.dto.Oauth2JwksKeyResponse;

import java.security.NoSuchAlgorithmException;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.text.ParseException;
import java.util.Base64;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class JwtValidator {

    /**
     * 验证 JWT 签名
     *
     * @param accessToken JWT 字符串
     * @param jwksKey 包含公钥信息的对象
     * @return 如果签名有效返回 true，否则返回 false
     */
    public boolean validateJwtSignature(String accessToken, Oauth2JwksKeyResponse jwksKey) {
        List<Oauth2JwksKeyResponse.Key> keys = jwksKey.getKeys();
        try {
            // 解析 JWT 字符串
            SignedJWT signedJWT = SignedJWT.parse(accessToken);

            Oauth2JwksKeyResponse.Key matchedKey = keys.stream()
                    .filter(key -> JWSAlgorithm.RS256.getName().equals(key.getAlg()) &&
                            "sig".equals(key.getUse()))
                    .findFirst()
                    .orElseThrow(() -> new IllegalArgumentException("No matching key found in JWKS"));

            // 如果存在 kid，则验证一致性
            String jwtKid = signedJWT.getHeader().getKeyID();
            if (jwtKid != null && !jwtKid.equals(matchedKey.getKid())) {
                throw new IllegalArgumentException("JWT key ID (kid) does not match the provided JWKS key");
            }


            // 构造 RSA 公钥
            RSAPublicKey publicKey = keys.getFirst().toRSAPublicKey();

            // 创建 JWSVerifier
            JWSVerifier verifier = new RSASSAVerifier(publicKey);

            // 验证签名
            return signedJWT.verify(verifier);
        } catch (ParseException | JOSEException | NoSuchAlgorithmException | InvalidKeySpecException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 验证 JWT 签名并返回payload内容
     *
     * @param accessToken JWT 字符串
     * @param jwksKey 包含公钥信息的对象
     * @return 包含内容的Map
     */
    public Map<String, Object> validateAndGetJwtContent(String accessToken, Oauth2JwksKeyResponse jwksKey) {
        List<Oauth2JwksKeyResponse.Key> keys = jwksKey.getKeys();
        try {
            // 解析 JWT 字符串
            SignedJWT signedJWT = SignedJWT.parse(accessToken);

            // 获取payload内容
            Payload payload = signedJWT.getPayload();
            Map<String, Object> payloadMap = payload.toJSONObject();

            // 匹配密钥
            Oauth2JwksKeyResponse.Key matchedKey = keys.stream()
                    .filter(key -> JWSAlgorithm.RS256.getName().equals(key.getAlg()) &&
                            "sig".equals(key.getUse()))
                    .findFirst()
                    .orElseThrow(() -> new IllegalArgumentException("No matching key found in JWKS"));

            // 验证kid一致性
            String jwtKid = signedJWT.getHeader().getKeyID();
            if (jwtKid != null && !jwtKid.equals(matchedKey.getKid())) {
                throw new IllegalArgumentException("JWT key ID (kid) does not match the provided JWKS key");
            }

            // 构造 RSA 公钥
            RSAPublicKey publicKey = matchedKey.toRSAPublicKey();

            // 创建 JWSVerifier
            JWSVerifier verifier = new RSASSAVerifier(publicKey);

            // 验证签名
            boolean isValid = signedJWT.verify(verifier);

            if (isValid) {
                return payloadMap;
            }

            throw new RuntimeException("JWT验证失败");

        } catch (ParseException | JOSEException | NoSuchAlgorithmException | InvalidKeySpecException e) {
            throw new RuntimeException("JWT验证失败", e);
        }
    }

}
